home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr53 / 122_01.zip / ITCOND < prev    next >
Text File  |  1993-06-02  |  11KB  |  341 lines

  1. ITERATION AND CONDITIONAL MENU:
  2. copyright (C) 1983 by E. E. Bergmann
  3. iteration
  4. BEGIN ... END
  5. BEGIN .. IF ... END
  6. DO LOOPs
  7. IF ... THEN and IF ... ELSE ... THEN
  8. "case" construction
  9. "recursion"
  10. :
  11. ::
  12. *********************************************************
  13. *                            *
  14. * PISTOL-Portably Implemented Stack Oriented Language   *
  15. *            Version 2.0            *
  16. * (C) 1983 by    Ernest E. Bergmann            *
  17. *        Physics, Building #16            *
  18. *        Lehigh Univerisity            *
  19. *        Bethlehem, Pa. 18015            *
  20. *                            *
  21. * Permission is hereby granted for all reproduction and *
  22. * distribution of this material provided this notice is *
  23. * included.                        *
  24. *                            *
  25. *********************************************************
  26. :
  27. ::
  28.     PISTOL provides four means for iterative execution
  29. of a sequence of words, namely:
  30.  
  31. BEGIN ... END
  32.  
  33.     executes words between BEGIN and END until a
  34. condition is satisfied.
  35.  
  36. BEGIN ... IF ... REPEAT
  37.  
  38.     is similar to BEGIN ... END except the condition is
  39. tested at the beginning of the loop; iteration terminates
  40. when the tested condition is false.
  41.  
  42. DO ... LOOP
  43.  
  44.     executes the words between DO and LOOP, running an
  45. index [accessible as "I"] from a lower to upper limit,
  46. incrementing by one each time.
  47.  
  48. DO ... n +LOOP
  49.  
  50.     executes the words between DO and +LOOP, running
  51. an index from a lower to an upper limit, incrementing 
  52. by n each time.
  53.  
  54.     Iterations may be nested subject to the normal
  55. restrictions on overlapping ranges, i.e. any iteration which
  56. is initiated within the range of another iteration must be
  57. terminated within that same range.  PISTOL has implemented a
  58. "check stack" to enforce this syntax rule and, as an aid to
  59. interactive programming, displays this stack in the prompt.
  60.  
  61. :
  62. ::
  63. BEGIN ... END
  64. =============
  65.     The BEGIN ... END syntax permits the user to execute
  66. a sequence of words and then, depending upon a computed
  67. logical variable, either loop back or continue on:
  68.  
  69. BEGIN word1 word2 .... wordm END
  70.  
  71.     The sequence word1, word2, ... is executed once.
  72. When END is reached, the top of the stack is popped and
  73. tested.  If it is true (non-zero) then control passes to the
  74. word following END.  If it is false (zero) then control
  75. passes back to the word following BEGIN.
  76.  
  77. An example:
  78.  
  79.     'EXAMPLE : BEGIN 1- DUP DUP = EQZ END DROP ;
  80.  
  81.     defines the word EXAMPLE which might be called
  82.     as follows:
  83.  
  84.     X>  5 EXAMPLE
  85.     4 3 2 1 0
  86.  
  87.     Each time through the loop, the top of the stack
  88.     (initially the number 5) is decremented, printed and
  89.     compared to zero.  If it is not zero, the loop is
  90.     repeated; the loop terminates when it becomes zero.
  91.  
  92. :
  93. ::
  94. BEGIN ... IF ... REPEAT
  95. =======================
  96.     BEGIN ... IF ... REPEAT is similar to BEGIN ... END
  97. except that the test is at the beginning of the loop.  The
  98. words between BEGIN and IF are executed. The top of the
  99. stack is then popped and tested.  If it is true (non-zero)
  100. the words between IF and REPEAT are executed and control
  101. passes back to the first word after BEGIN. If the top of the
  102. stack had been tested false (zero) control would have passed
  103. to the word following REPEAT.
  104.  
  105. An example:
  106.  
  107.     'LENGTH : 0 BEGIN SWAP DUP IF W@ SWAP 1+ REPEAT UNDER ;
  108.  
  109.     might be used to determine the length of a chain of
  110.     pointers terminated by zero.  The initial pointer
  111.     would be placed on the stack and LENGTH would be
  112.     invoked.  If one could not place the test at the
  113.     beginning of the iteration, one would have a problem
  114.     with a zero length chain (a zero initially on the
  115.      stack).
  116.  
  117.  
  118. :
  119. ::
  120. DO LOOPS
  121. ========
  122.     A DO LOOP facility is provided by PISTOL for indexing
  123. through a sequence of words.  There are two forms of DO LOOP:
  124.  
  125. HIGH LOW DO word1 word2 ... wordn LOOP
  126.  
  127. HIGH LOW DO word1 word2 ... wordn STEP +LOOP
  128.  
  129.     The limits HIGH and LOW (the top two stack entries) are
  130. compared.  If HIGH is less than or equal to LOW, control passes
  131. to the word following LOOP or +LOOP.  Otherwise, the sequence
  132. word1, word2, ... is executed.  LOOP causes the lower limit,
  133. LOW to be incremented and compared to the upper limit, HIGH.
  134. If LOW is greater than or equal to HIGH, the loop is
  135. terminated.  Otherwise another iteration is performed. The
  136. +LOOP is identical to LOOP except that the LOW is incremented
  137. by the word on top of stack, STEP. Normally, STEP would be a
  138. positive number.
  139.  
  140.     Within the range of a loop, the current value of the
  141. loop index is available by using "I".  If DO LOOPs are nested,
  142. I contains always the value of the innermost index.  The next
  143. outer indices are available using the words, J and K.  The word
  144. I' is used to obtain the value of (HIGH+LOW-I-1).  This is used
  145. to run an index backwards from HIGH-1 to LOW .  The words J'
  146. and K' are similarly defined.  When parenthesis (iteration
  147. brackets) are nested with DO LOOPs, they count as one level of
  148. indexing.  When I is used within the range of an iteration
  149. bracket the current iteration count (which runs from its
  150. initial value downwards to one) is placed on stack.
  151.  
  152.     The word EXIT causes the innermost loop in which
  153. it is embedded to terminate unconditionally.
  154.  
  155. Some examples:
  156.  
  157.     5 0 DO I = LOOP
  158.  
  159.     causes the numbers 0 to 4, inclusive to be typed out.
  160.  
  161.     5 0 DO 5 0 DO J 5 * I + = LOOP CR LOOP
  162.  
  163.     causes the numbers 0 through 24 inclusive to be
  164.     typed out as 5 lines of 5 numbers each.
  165.  
  166.     5 0 DO I' = LOOP
  167.  
  168.     causes the numbers 4 ... 0, inclusive to be output.
  169.  
  170.     0 21 1 DO I + DUP = 2 +LOOP DROP
  171.  
  172.     types out the first 10 perfect squares starting with 1.
  173.  
  174.     When using I' (or J' or K') in conjunction with +LOOP,
  175. HIGH should be replaced by HIGH - STEP + 1  if it is desired
  176. to produce the same set of indices as with I .  For example:
  177.  
  178.     X>  24 0  DO I = 4 +LOOP
  179.     0 4 8 12 16 20
  180.  
  181.     X>  24 0 DO I' = 4 +LOOP
  182.     23 19 15 11 7 3 1
  183.  
  184.     X>  24 4 - 1+ 0 DO I' = 4 +LOOP
  185.     20 16 12 8 4 0
  186.  
  187. :
  188. ::
  189. CONDITIONALS
  190. ============
  191.  
  192.     PISTOL has a powerful IF ... ELSE ... THEN construction
  193. which allows moderately complex logical tests to be performed.
  194. In addition, for more complex situations an OFCASE ... ENDCASE
  195. n-branch construction is provided also [the"CASE"construction].
  196. Conditionals may be nested within each other and within
  197. iteration loops with the same restrictions that apply to
  198. iterations.  The check stack enforces that proper nesting is
  199. maintained and will issue fatal error messages otherwise.  The
  200. prompt provides the user with information on the current
  201. nesting status.
  202.  
  203.     For purposes of the conditional, "true" is considered
  204. to be any non-zero value; "false" is any zero value. [The
  205. "best" true value is -1, viz. all 1's in binary, in that
  206. "-1 N AND" will be always "true" unless N is "false".]
  207.  
  208. val IF true1 true2 ... ELSE false1 false2 ... THEN
  209.  
  210.     The top of stack, val is tested and
  211.  
  212.     if true (non-zero), the words true1,true2,...
  213.     are executed; control passes then to the word
  214.     following THEN,
  215.  
  216.     otherwise, if false (zero) control passes to false1 ,
  217.     false2 ... ; control passes then to the word
  218.     following THEN, 
  219.  
  220. Two examples:
  221.  
  222.     'ABS : DUP LTZ IF MINUS THEN ;
  223.  
  224.     defines the word ABS which replaces the top of stack
  225.     with its absolute value.
  226.  
  227.     'MAX : DDUP GT IF DROP ELSE UNDER THEN ;
  228.  
  229.     defines the word MAX which compares the top two stack
  230.     entries and leaves the larger of the two.
  231.  
  232. :
  233. ::
  234.     The CASE construction simplifies many programs where
  235. the value of a variable is used to choose among many
  236. possibilities. Its syntax is necessarily more complex:
  237.  
  238. value    OFCASE    <test1> C: <action1> ;C
  239.         <test2> C: <action2> ;C
  240.         .    .    .    .
  241.         .    .    .    .
  242.         <testn> C: <actionn> ;C
  243.     ENDCASE
  244.  
  245.     The liberal use of carriage returns and tabs in the
  246. coding improves readability, but is not required by the syntax.
  247. OFCASE saves value and replaces it on the stack before each
  248. test. If <test1> is true then <action1> (which may be any
  249. number of words) is carried out and control skips to the first
  250. word after ENDCASE. Otherwise, if <test1> is false, value is
  251. again placed on stack and <test2> performed;  if it proves true
  252. then <action2> is done and control passes to the word following
  253. ENDCASE, etc. Thus the first successful test selects the action
  254. performed.
  255.  
  256.     If every test, including <testn> is false, control
  257. reaches ENDCASE and a fatal error message is generated.
  258. An example should clarify this (notice how the prompt changes):
  259.  
  260. X> 'SPELL : OFCASE
  261. X:C> 0 EQ C: 'ZERO ;C
  262. X:C> 1 EQ C: 'ONE ;C
  263. X:C> 2 EQ C: 'TWO ;C
  264. X:C> 2 GT C: 'MANY ;C
  265. X:C> ENDCASE MSG ;
  266.  
  267. When testing this definition one finds:
  268.  
  269. X> 2 SPELL
  270. TWO
  271. X> 3 SPELL
  272. MANY
  273. X> -1 SPELL
  274. CASE EXECUTION ERROR AT 11672 FOR THE VALUE -1       PISTOL
  275.  
  276.     The fatal error message provides the address of ENDCASE
  277. and the value that created the problem.
  278.  
  279.     OFCASE does not use the loop stack but uses its own
  280. "CASE" stack;  the words I , J , K , I' , J' , K' and EXIT will
  281. properly access the DO...LOOP counters when intermixed with
  282. this structure. The words, ICASE and JCASE, access the case
  283. variable of the innermost OFCASE structure and the next to
  284. innermost OFCASE structure, respectively.  They are somewhat
  285. analogous to the words I and J of the DO LOOP structure.
  286.  
  287. :
  288. ::
  289. RECURSION
  290. =========
  291.     Normally, a procedure cannot invoke itself because it
  292. is compiled before its own name is recorded;  therefore the
  293. word RECURSE is provided as a "stand-in" for the name of the
  294. procedure being defined.  This word also provides the means for
  295. recursing within the compile buffer, itself.  For example,
  296. one might wish to define FACTORIAL by:
  297.  
  298. 'FACTORIAL : DUP 1 EQ LNOT IF
  299.         DUP 1 - FACTORIAL * THEN
  300.        ;
  301.  
  302. However, FACTORIAL is not yet defined until this current
  303. definition has been compiled.  We should use the word,
  304. RECURSE, instead:
  305.  
  306. 'FACTORIAL : DUP 1 EQ LNOT IF
  307.         DUP 1 - RECURSE * THEN
  308.        ;
  309.  
  310.     It is possible to use RECURSE for directly executing
  311. code from the compile buffer as well:
  312.  
  313. X> 3
  314. 1X> DUP 1 EQ LNOT IF DUP 1 - RECURSE * THEN
  315. 1X> =
  316. 6
  317.  
  318.     For recursion which requires forward references one
  319. has to make an extra effort (as one does in PASCAL, which
  320. requires the use of the reserved word, FORWARD). In PISTOL
  321. we must define first a variable, say, FORW, which is
  322. destined to contain the address of the forward reference.
  323. One defines then those routines that invoke the
  324. forward-referenced routine with the code:
  325.  
  326.     ... FORW W@ EXEC ...
  327.  
  328. Eventually, one is in the position to define the routine that
  329. is needed to complete the recursive circle, say, LAST.  After
  330. defining LAST the recursive loop is established with:
  331.  
  332.     'LAST ADDRESS FORW W!
  333.  
  334. which records the address of LAST in the variable, FORW .
  335.  
  336. :
  337. IAL is not yet defined until this current
  338. definition has been compiled.  We should use the word,
  339. RECURSE, instead:
  340.  
  341. 'FACT